এর পরের অংশটুকু পুরোপুরি ব্যাবহারিক। প্রোগ্রামিং করার ব্যবস্থা আছে (কম্পিউটারে কিংবা স্মার্টফোনে) শুধু সেরকম পরিবেশে পরের অংশটুকু শিক্ষার্থীর জন্য অর্থপূর্ণ বলে বিবেচিত হবে।
সি একটি অত্যন্ত শক্তিশালী প্রোগ্রামিং ভাষা। সি ভাষা ব্যবহার করে বিভিন্ন রকমের প্রোগ্রাম তৈরি করা যায়। যেমন-
সি ভাষার কম্পাইলার
কম্পিউটারে সি ভাষায় প্রোগ্রাম লিখে চালাতে হলে প্রথমে ইন্টারনেট থেকে একটি কম্পাইলার সফটওয়্যার ডাউনলোড এবং ইনস্টল করে নিতে হবে। প্রথমে একটি টেক্সট ফাইলে প্রোগ্রাম লিখে সেভ করতে হবে। এই ফাইলের এক্সটেনশন হবে .c (অর্থাৎ, ফাইলটির নামের শেষে .c কথাটি থাকবে, যেমন- program1.c)। এরপরে ফাইলটি কম্পাইলার ব্যবহার করে কম্পাইল করতে হবে। কম্পাইল করার পরে একটি এক্সিকিউটেবল ফাইল তৈরি হবে। উইন্ডোজ অপারেটিং সিস্টেমে এই এক্সিকিউটেবল ফাইলের এক্সটেনশন হয় .exe (যেমন— program1.exe) ।
প্রোগ্রাম কম্পাইলারগুলো সাধারণত কমান্ড লাইনভিত্তিক হয়। অর্থাৎ, কমান্ড লাইন অ্যাপ্লিকেশনে নির্দেশ টাইপ করে প্রোগ্রাম কম্পাইল করতে হয়। তবে বর্তমানে প্রোগ্রামারদের কাজ সহজ করার জন্য কিছু আইডিই সফটওয়্যার পাওয়া যায়, যেখানে, একই সঙ্গে কোড লেখা, কম্পাইল করাসহ বিভিন্ন কাজ করা যায়।
ইন্টারনেটে এরকম বিভিন্ন আইডিই (IDE) সফটওয়্যার বিনামূল্যে পাওয়া যায়। তারমধ্যে সি ভাষার জন্য ব্যবহৃত একটি আইডিই হচ্ছে কোডব্লকস (Code::blocks)। এছাড়া নেটবিনস, একলিপ্স, মাইক্রোসফট ভিজুয়াল স্টুডিওসহ বিভিন্ন সফটওয়্যার দিয়েও সি ভাষায় প্রোগ্রামিং করা যায়। এসব সফটওয়্যারের পাশাপাশি অ্যান্ড্রয়েড অপারেটিং সিস্টেম চালিত মোবাইল ফোনের জন্যও বিভিন্ন কম্পাইলার অ্যাপ পাওয়া যায়।
হ্যালো ওয়ার্ল্ড (Hello World)
এখন আমরা একটি সি প্রোগ্রাম দেখব।
1
2
3
4
5
6
7
8
#include
int main ()
printf("Hello World!");
return 0;
}
প্রোগ্রাম 5.1
কোড লেখার পরে প্রোগ্রামটি সেভ করতে হবে। সেভ করার সময় ফাইলের এক্সটেনশন দিতে হবে .CI এরপর
প্রোগ্রামটি কম্পাইল এবং রান করতে হবে। প্রোগ্রামটি রান করলে আউটপুট আসবে এরকম—
Hello World!
সি ভাষায় তৈরি প্রোগ্রামে একটি নির্দিষ্ট কাজ করার জন্য একটি ফাংশন তৈরি করা হয়। ফাংশনের ভেতরে
ওই কাজটি সম্পন্ন করার জন্য প্রয়োজনীয় কোড লেখা থাকে।
উপরের প্রোগ্রামের তৃতীয় লাইনে রয়েছে, int main()। একে বলা হয় main() ফাংশন। চতুর্থ এবং অষ্টম লাইনে দুটি ব্র্যাকেট (দ্বিতীয় বন্ধনী) চিহ্ন দিয়ে বোঝানো হচ্ছে main() ফাংশনটি চতুর্থ লাইনে শুরু হয়েছে এবং অষ্টম লাইনে শেষ হয়েছে। পঞ্চম ও সপ্তম লাইনে দুটি নির্দেশ দেওয়া হয়েছে। আর ষষ্ঠ লাইনটি ফাঁকা রাখা হয়েছে।
সি ভাষায় লেখা যে কোনো প্রোগ্রাম চলা শুরু হয় main() ফাংশন থেকে। যেমন— উপরের কোডে তৃতীয় লাইনে main() ফাংশন থেকে এই প্রোগ্রামটি চলতে আরম্ভ করবে। একটি প্রোগ্রামে কেবল একটি main () ফাংশনই লেখা হয়।
এর পরে পঞ্চম লাইনে রয়েছে printf ("Hello World!") স্টেটমেন্ট। printf() একটি ফাংশন, যার কাজ
হচ্ছে স্ক্রিনে কোনো কিছু প্রিন্ট করা। যেমন— এই প্রোগ্রামের ক্ষেত্রে এই স্টেটমেন্টটি স্ক্রিনে Hello World!
কথাটি প্রিন্ট করছে। printf() ফাংশনটি কীভাবে প্রিন্ট করার কাজটি করবে, সেটি এই প্রোগ্রামে কোথাও বলা নেই, তবে stdio.h নামক একটি ফাইলে বলা আছে। একে বলে হেডার (header) ফাইল। হেডার ফাইলে বিভিন্ন ফাংশন তৈরি করে দেওয়া থাকে। এই ফাংশনগুলো ব্যবহার করার জন্য হেডার ফাইলটি প্রোগ্রামে অন্তর্ভুক্ত করতে হয়। প্রথম লাইনে #include
প্রোগ্রামের সপ্তম লাইনে লেখা আছে, return O। এটি মেইন ফাংশনের শেষ লাইন। এই লাইনটি কী কাজ করে তা নিয়ে এ অধ্যায়ের পরবর্তী অংশে আলোচনা করা হয়েছে। এই লাইনটি চলার পরে এই প্রোগ্রামটি চলা শেষ হবে।
নিজে করি ১ : একটি প্রোগ্রাম লিখতে হবে, যেটি স্ক্রিনে I love Bangladesh. কথাটি প্রিন্ট করবে।
ডেটা টাইপ (Types of Data)
আমরা জানি কম্পিউটার প্রসেসর বিভিন্ন হিসাব-নিকাশ করে। এই হিসাব-নিকাশগুলো বিভিন্ন ডেটার উপরে করা হয়। সি প্রোগ্রামিং ভাষায় বেশ কিছু ডেটা টাইপ রয়েছে, অর্থাৎ বিভিন্ন ধরনের ডেটা নিয়ে কাজ করার ব্যবস্থা রয়েছে। এর মধ্যে উল্লেখযোগ্য হচ্ছে— char, int, float ও double। নিচে ডেটা টাইপগুলো নিয়ে সংক্ষিপ্ত আলোচনা করা হলো-
char
এটি হচ্ছে character-এর প্রথম চারটি অক্ষর। এ ধরনের ডেটা টাইপ একটিমাত্র অক্ষর (বর্ণ, অংক, যতিচিহ্ন ইত্যাদি) ধারণ করতে পারে, যেমন- 'a', 'D', '5', '!' ইত্যাদি। এটি কম্পিউটারের মেমোরিতে সাধারণত এক ৰাইট (অর্থাৎ, আট বিট) জায়গা দখল করে। তাহলে এ ধরনের ডেটা টাইপে 2° বা 256টি পৃথক ভেটা রাখা যায়। 256টি জিনিস কিন্তু একটি ভ্যারিয়েবলে একসঙ্গে রাখা যায় না, একটি ভ্যারিয়েবলে একই সময়ে কেবল একটি ডেটা রাখা যায়, আর char টাইপের ডেটার ক্ষেত্রে সম্ভাব্য 256টি মালের যে কোনো একটি রাধা যায়।
একটি বিটে যে কোনো সময়ে রাখা যায় 0 অথবা, 1। অর্থাৎ, একটি বিট দিয়ে দুটি ভিন্ন জিনিস প্রকাশ করা যায়। আবার দুইটি বিট দিয়ে প্রকাশ করা যায় চারটি ভিন্ন জিনিস— 0001, 10 এবং 11। একইভাবে তিনটি বিট দিয়ে প্রকাশ করা যায় আটটি ভিন্ন জিনিস - 000001010, 011, 100, 101, 110, এবং 111। তাহলে n সংখ্যক বিট দিয়ে প্রকাশ করা যায়, 2” -সংখ্যক ভিন্ন জিনিস।
int
Integer শব্দের অর্থ পূর্ণসংখ্যা। এই শব্দের প্রথম তিনটি অক্ষর নিরে int ডেটা টাইপের নামকরণ করা হয়েছে। এ ধরনের ডেটা টাইপে পূর্ণসংখ্যা রাখা যায়। একটি int টাইপের ডেটা সাধারণত কম্পিউটারের মেমোরিতে চার বাইট (অর্থাৎ, 32 বিট) জায়গা দখল করে। যেহেতু এর সাইজ 32 বিট, তাই এতে সম্ভাব্য 232 বা 4294957295 রকমের সংখ্যা রাখা যায়। আর সংখ্যা যেহেতু ধনাত্মক ও ঋণাত্মক উভয় জাতীয় হতে পারে, ভাই – 2147483648 থেকে 2147483647 সীমার মধ্যে যে কোনো সংখ্যা int টাইপের ডেটাতে ধারণ করা যায়।
float
দশমিকযুক্ত সংখ্যা অর্থাৎ, floating point number রাখার জন্য float ডেটা টাইপ ব্যবহার করা হয়। এটি মেমোরিতে সাধারণত চার বাইট জায়গা দখল করে।
double
এটিও দশমিক যুক্ত সংখ্যা রাখার জন্য ব্যবহার করা হয়। তবে এটি সাধারণত কম্পিউটারের মেমোরিতে
আট বাইট জায়গা নেয়।
কয়েকটি প্রোগ্রাম লিখে উল্লিখিত ডেটা টাইপের ব্যবহার দেখানো হলো-
#include
char ch;
ch- 'X'; printf("The character is %c", ch);
return 0;
প্রোগ্রাম 5.2
প্রোগ্রামটি কম্পাইল ও রান করলে আউটপুট আসবে The character is X ।
এই প্রোগ্রামে char ch লিখে char টাইপের একটি ভ্যারিয়েবল (variable) তৈরি করা হয়েছে, যার নাম দেওয়া হয়েছে ch। এখানে ch-এর বদলে অন্য নামও ব্যবহার করা যেত। একে ভ্যারিয়েবল বলা হয়। ক্যারেক্টার টাইপের ডেটা প্রিন্ট করার জন্য %c ব্যবহার করা হয়। একে বলা হয় ফরম্যাট স্পেসিফায়ার (format specifier)। নিচের টেবিলে বিভিন্ন ডেটা টাইপের ফরম্যাট স্পেসিফায়ার দেখানো হলো-
ডেটা টাইপ
char
%C
ফরম্যাট স্পেসিফায়ার
int
%d
%f
float
%lf (এখানে | হচ্ছে ছোট হাতের ইংরেজি L অক্ষর)
double
সি প্রোগ্রামে ভ্যারিয়েবলের নাম লেখার ক্ষেত্রে কিছু নিয়মকানুন রয়েছে। ভ্যারিয়েবলের নামে কেবল বর্ণ, অংক এবং বিশেষ চিহ্ন ব্যবহার করা যাবে। তবে নামের প্রথম অক্ষরটি কোনো অংক হতে পারবে না। Variable এ underscore () এবং doller সাইন ($) ছাড়া অন্য কোনো স্পেশাল ক্যারেক্টার (@, !, ...ইত্যাদি) এবং punctuation character (,.: ইত্যাদি) বা কোনো ধরনের অপারেটর ব্যবহার %, +, -... করা যাবে না। Variable নামে কোনো স্পেস দেয়া যাবে না। C তে uppercase and lowercase character এর মধ্যে পার্থক্য আছে যার কারণে C কে case sensitive programming language বলা হয়। তাই aaa, AAA, Aaa ba Net, net, NeT ইত্যাদি variable এর মান এক নয়। স্পেশালি কোনো কী-ওয়ার্ডকে variable এর নাম হিসেবে ব্যবহার করা যাবে না।
সঠিক ভ্যারিয়েবল নামের উদাহরণ
ভুল ভ্যারিয়েবল নামের উদাহরণ
age final_result
Ostudent final result
student_1_marks
greetings!
my,name
student0
current date
উদাহরণ ২
একটি ক্যারেক্টার টাইপের ভ্যারিয়েবল char টাইপের যে কোনো ডেটা ধারণ করতে পারে। বিষয়টি একটি
প্রোগ্রাম লিখে দেখা যাক ।
#include
char ch;
ch = 'x' ;
printf("Value stored in ch is %c\n", ch);
ch = 'y'; printf("Value stored in ch is %c\n", ch); return 0;
প্রোগ্রাম 5.3
উপরের প্রোগ্রামটি কম্পাইল করে রান করলে নিচের মতো আউটপুট পাওয়া যাবে।
Value stored in ch is x Value stored in ch is y
আউটপুট দেখে বোঝার চেষ্টা করতে হবে যে প্রোগ্রামটিতে কী কাজ হচ্ছে। এখানে printf() ফাংশনের ভেতরে \n ব্যবহার করা হয়েছে। \n-এর মানে হচ্ছে নিউ লাইন (new line), অর্থাৎ এটি প্রিন্ট করলে আউটপুটের পরবর্তী অংশ স্ক্রিনে নতুন লাইনে চলে যাবে। যদি printf() ফাংশনের ভেতরে \n ব্যবহার করা না হতো, তবে আউটপুট হতো এরকম—
Value stored in ch is x Value stored in ch is y
একটি ভ্যারিয়েবলে যখন কোনো মান রাখা হয় (যেমন— ch = 'x';), একে বলা হয় ch-এর মধ্যে 'x' অ্যাসাইন করা এবং অপারেশনটির নাম হচ্ছে অ্যাসাইনমেন্ট অপারেশন। একটি ভ্যারিয়েবলে একই সময়ে কেবল একটি মান অ্যাসাইন করা যায়।
নিজে করি ২ : প্রোগ্রাম 5.3-এ ch-এর বদলে বিভিন্ন নামের ভ্যারিয়েবল ব্যবহার করে পরীক্ষা-নিরীক্ষা
করতে হবে। প্রতিবার প্রোগ্রাম সেভ করে কম্পাইল ও রান করতে হবে।
উদাহরণ ৩
এখন একটি প্রোগ্রাম দেখানো হবে, যার কাজ হচ্ছে দুটি সংখ্যার যোগফল, বিয়োগফল, গুণফল ও ভাগফল প্রকাশ করা—
#include
int number1, number2;
number1 = 12;
number 2 = 4;
printf("number 1 + number2 = %d\n", number 1 + number 2) ;
printf("number 1 - number2
= sd\n", number 1 - number 2 ) ;
printf("number 1 * number2 = d\n", number 1 * number 2) ; printf("number 1 / number 2 = %d\n", number 1 / number 2) ;
return 0;
}
আউটপুট
number 1 + number2 = 16
number1 - number2 8 =
number1 * number2 48
=
number 1 / number 2 3
=
ইন্টিজার টাইপের ডেটা প্রিন্ট করার জন্য %d ব্যবহার করা হয়। আর গুণচিহ্ন ও ভাগচিহ্ন হচ্ছে, যথাক্রমে * ও /। উপরের প্রোগ্রামটিতে চাইলে আরেকটি ভ্যারিয়েবল তৈরি করা যায়, যেখানে বিভিন্ন গাণিতিক অপারেশনের ফলাফল রাখা হবে।
#include
int main()
{
int number1, number2, result;
number 1 = 12 ; number 2 = 4;
result = number1 + number2 ;
printf ("number 1 + number 2 = %d\n", result);
result = number 1 - number2 ;
printf("number 1 = number 2 = %d\n", result);
result = number 1 * number2 ;
printf("number1 * number 2
%d\n", result);
= result = number 1 / number2 ;
printf("number 1 / number 2 = %d\n", result);
return 0;
প্রোগ্রাম 5.5
উল্লেখ্য যে, number1 + number2 হচ্ছে একটি এক্সপ্রেশন (expression)। সি প্রোগ্রামিংয়ে এক্সপ্রেশন বলতে বোঝানো হয় কিছু কোড যা একটি মান প্রকাশ করে। আবার number2 = 4; হচ্ছে একটি স্টেটমেন্ট (statement)। একটি স্টেটমেন্ট দিয়ে একটি কাজ বোঝানো হয়। এখানে কাজটি হচ্ছে number2 নামক ভ্যারিয়েবলে 4 রাখা। আবার, result = number1 + number2; একটি স্টেটমেন্ট। এটি দ্বারা বোঝানো হচ্ছে number1 + number2 এক্সপ্রেশনটি এক্সিকিউট করে যে মান পাওয়া যাবে, সেটি result নামক ভ্যারিয়েবলে রাখা। printf("number 1 / number2 = %d\n", result); - এটিও একটি স্টেটমেন্ট। প্রতিটি স্টেটমেন্টের শেষে একটি সেমিকোলন চিহ্ন দেওয়া হয়।
কি-ওয়ার্ড (Keyword)
সি প্রোগ্রামিং ভাষায় বেশ কিছু সংরক্ষিত শব্দ আছে, যেগুলো হচ্ছে সি ভাষার অংশ। তাই এসব শব্দকে ভ্যারিয়েবলের নাম কিংবা ফাংশনের নাম হিসেবে ব্যবহার করা যায় না। এসব শব্দকে বলা হয় কি-ওয়ার্ড। নিচের টেবিলে C ভাষার ANSI (ANSI : American National Standard Institute) কি-ওয়ার্ডের একটি তালিকা দেওয়া হলো :
auto
break
double
else
int
long
struct
switch
case
char
enum
extern
register
return
typedef
union
const
continue
default
float
short signed
unsigned
for
goto
if
sizeof
static
void
volatile
while
do
এ সমস্ত কি-ওয়ার্ড মুখস্থ করার প্রয়োজন নেই। কেবল খেয়াল রাখতে হবে, এই নামগুলো ভ্যারিয়েবল কিংবা ফাংশনের নাম হিসেবে ব্যবহার করা যাবে না।
ইনপুট আউটপুট স্টেটমেন্ট (Input Output Statements )
ইতোমধ্যে দেখানো হয়েছে যে, কীভাবে স্ক্রিনে প্রিন্ট করতে হয়, অর্থাৎ, আউটপুট দিতে হয়। এবারে ইনপুট নেওয়ার পালা। নিচের প্রোগ্রামটি ব্যবহারকারীর কাছ থেকে দুটি সংখ্যা ইনপুট নেবে এবং তাদের যোগফল আউটপুটে দেখাবে।
উদাহরণ ৪
#include
{
int n1, n2 ;
scanf("%d %d", &n1, &n2); printf("%d\n", n1+n2) ;
return 0;
প্রোগ্রাম 5.6
প্রোগ্রামটি কম্পাইল করে রান করলে সেটি ব্যবহারকারীর ইনপুটের জন্য অপেক্ষা করবে (চিত্র 5.7), দুটি সংখ্যা লিখে কি-বোর্ডের এন্টার কি (key) চাপলে তখন আউটপুট দেখাবে (চিত্র 5.8)।
CAUsers\rafit\Documents\Untitled1.exe.
X
চিত্র 5.7 : কমান্ড লাইনে কিছু প্রিন্ট না করে ব্যবহারকারীর ইনপুটের জন্য অপেক্ষা করছে
C:\Users\rafit\Documents\Untitled1.exe
36
9
Process returned 0 (0x0)
Press any key to continue.
X
execution time:
110.476 s
চিত্র 5.8 : দুটি সংখ্যা টাইপ করে কি-বোর্ডে Enter কি চাপার পরে ফলাফল পাওয়া গেল
তাহলে দেখা যাচ্ছে, scanf() ফাংশনটি দিয়ে ইনপুট নেওয়া হয়। আর যেসব ভ্যারিয়েবলের মান ইনপুট নেওয়া হচ্ছে, তাদের আগে অ্যামপারসেন্ড (&) চিহ্ন ব্যবহার করা হয়। আর ফাংশনটির ভেতরে printf( ) ফাংশনের মতো একই ফরম্যাট স্পেসিফায়ার ব্যবহার করা হয়।
উদাহরণ ৫
একটি প্রোগ্রাম লিখতে হবে, যা কোনো তাপমাত্রাকে সেলসিয়াস এককে ইনপুট নেবে এবং ফারেনহাইট এককে আউটপুট দেবে। প্রোগ্রাম লেখার আগে প্রোগ্রামটির ফ্লোচার্ট তৈরি করতে হবে। সেলসিয়াস থেকে ফারেনহাইটে রূপান্তর করার সূত্র হচ্ছে, f = F-32 সুতরাং F = 9 / 5 x C + 32
ফ্লোচার্টটি 5.9 চিত্রে দেখানো হলো।
শুরু
C- এর মান ইনপুট
F = 9 / 5 x C + 32
F-এর মান প্রিন্ট
শুরু
চিত্র 5.7 : সেলসিয়াস থেকে ফারেনহাইট রূপান্তরের ফ্লোচার্ট
আর প্রোগ্রামটি হবে এরকম-
#include
{
double C, F; scanf("%lf", &C) ; F = 9/5 * C + 32 ; printf("%lf\n", F); return 0;
}
প্রোগ্রাম 5.7
নিজে করি ৩ : একটি প্রোগ্রাম লিখতে হবে, যা কোনো তাপমাত্রাকে ফারেনহাইট এককে ইনপুট নেবে এবং সেলসিয়াস এককে আউটপুট দেবে।
কনডিশনাল স্টেটমেন্ট (Conditional Statements)
কম্পিউটার প্রোগ্রাম এমনভাবে লেখা যায়, যেন প্রোগ্রামটি বিভিন্ন শর্তের উপর ভিত্তি করে সিদ্ধান্ত গ্রহণ করতে পারে। এই শর্তকে প্রোগ্রামিংয়ের ভাষায় বলে কন্ডিশন (condition), আর যে এক্সপ্রেশন ব্যবহার করে শর্ত তৈরি করা হয়, তাকে বলে কন্ডিশনাল এক্সপ্রেশন (conditional expression)। কন্ডিশনাল এক্সপ্রেশন যখন এক্সিকিউট হয়, তখন তার ফলাফল হবে হয় সত্য (True), নয়তো মিথ্যা (False ) ।
রিলেশনাল অপারেটর (Relational Operator)
সি প্রোগ্রামিং ভাষায়, দুটি সংখ্যা তুলনা করার জন্য ছয়টি অপারেটর আছে, এগুলোকে বলা হয় রিলেশনাল অপারেটর। নিচের টেবিলে সেগুলো দেখানো হলো-
অপারেটর
ব্যাখ্যা
| দুটি সংখ্যা সমান কি না সেটি পরীক্ষা করা হয়। সমান হলে ফলাফল সত্য আর সমান না
হলে ফলাফল মিথ্যা হয়।
দুটি সংখ্যা অসমান কি না সেটি পরীক্ষা করা হয়। অসমান হলে ফলাফল সত্য আর সমান
হলে ফলাফল মিথ্যা হয়।
==
!=
>
দুটি সংখ্যার মধ্যে বামপক্ষ ডানপক্ষের চেয়ে বড় কি না সেটি পরীক্ষা করা হয়, বামপক্ষ যদি বড় হয় তাহলে ফলাফল সত্য, আর তা না হলে ফলাফল মিথ্যা। দুটি সংখ্যার মধ্যে বামপক্ষ ডানপক্ষের চেয়ে বড় অথবা সমান কি না সেটি পরীক্ষা করা হয়, বামপক্ষ যদি বড় হয়, অথবা ডানপক্ষের সমান হয় তাহলে ফলাফল সত্য, আর তা না হলে
>=
ফলাফল মিথ্যা।
দুটি সংখ্যার মধ্যে বামপক্ষ ডানপক্ষের চেয়ে ছোট কি না সেটি পরীক্ষা করা হয়, বামপক্ষ যদি ছোট হয় তাহলে ফলাফল সত্য, আর তা না হলে ফলাফল মিথ্যা।
দুটি সংখ্যার মধ্যে বামপক্ষ ডানপক্ষের চেয়ে ছোট অথবা সমান কি না সেটি পরীক্ষা করা
হয়, বামপক্ষ যদি ছোট হয়, অথবা ডানপক্ষের সমান হয়, তাহলে ফলাফল সত্য, আর তা না
হলে ফলাফল মিথ্যা।
if স্টেটমেন্ট
টেবিল 5.1
সি প্রোগ্রামিং ভাষায় বিভিন্ন শর্ত পরীক্ষার জন্য if স্টেটমেন্ট ব্যবহার করা হয়।
if (conditional expression) {
statement 1;
}
প্রথম বন্ধনীর ভেতরের conditional expression যদি সত্য হয়, তাহলে if ব্লকের ভেতরের কাজ হবে। কন্ডিশনাল এক্সপ্রেশনের পরে দ্বিতীয় বন্ধনী দিয়ে ব্লকটি আবদ্ধ থাকে। ব্লকের ভেতরে এক বা একাধিক স্টেটমেন্ট থাকতে পারে।
উদাহরণ ৬
এখন একটি প্রোগ্রাম লেখা হবে, যেটি দুটি সংখ্যার মধ্যে তুলনা করে বের করবে তারা সমান কি না ।
#include
int n1 = 5, n2 = 7; if (n1 == n2 ) { } printf("Numbers are equal");
return 0;
প্রোগ্রাম 5.8
প্রোগ্রামটি রান করলে আমরা আউটপুটে কিছুই দেখতে পাব না। কেননা, if-এর ভেতরে ব্যবহৃত কন্ডিশনাল
এক্সপ্রেশনটির মান মিথ্যা। তাই if-ব্লকের ভেতরের কোড এক্সিকিউট হয়নি। if-else স্টেটমেন্ট : Conditional expression সঠিক হলে এক ধরনের কাজ এবং conditional
expression সঠিক না হলে অন্য ধরনের কাজ সম্পাদন করতে হয় সেক্ষেত্রে if else স্টেটমেন্ট ব্যবহৃত হয়।
if (conditinal expression)
{
statement, if condition is true; }
else
{ statement, if condition is false;
#include
int n1 = 5, n2 = 7; if (nl == n2 )
{
}
printf("Numbers are equal !" ) ;
else {
}
printf("Numbers are not equal !" ) ;
return 0;
}
প্রোগ্রাম 5.9
এই প্রোগ্রামটি রান করলে আমরা এরকম আউটপুট দেখতে পাব—
Numbers are not equal.
if-এর সঙ্গে ব্যবহৃত কন্ডিশনাল এক্সপ্রেশনটি (n1 == n2) মিথ্যা হওয়ায় if ব্লকের কোড এক্সিকিউট হয়নি, else ব্লকের কোডগুলো এক্সিকিউট হয়েছে। আবার যদি, n1, এবং n2 দুটি ভ্যারিয়েবলের মান সমান হতো, তাহলে if ব্লকের কোড এক্সিকিউট হতো, কিন্তু else ব্লকের কোড এক্সিকিউট হতো না। তখন আমরা আউটপুট দেখতাম—
Numbers are equal.
আবার আরেকটি ব্লক আছে, else if. কখনো যদি এমন প্রোগ্রাম লেখা হয় যে একটি শর্তের পরে অন্য একটি শর্ত পরীক্ষা করা হবে, তখন if-এর সঙ্গে এক বা একাধিক else if ব্লক ব্যবহার করা হয়। যেমন— else if chain স্টেটমেন্ট : conditional expression যদি একাধিক হয় তাহলে else if স্টেটমেন্ট ব্যবহৃত হয়।
if (conditional expression 1) statement, if conditional expression-1 is true; } else if (conditional expression-2) statement, if conditional expression - 2 is true, }
else
statement, if both conditions are false;
}
#include
{
int n1 = 5, n2 = 7; if (n1 == n2 )
{
printf("Numbers are equal"); } else if (n1 > n2 )
{ } else printf("n1 is greater than n2 ) ;
{
printf("nl is smaller than n2");
} return 0;
প্রোগ্রাম 5.10
এক্ষেত্রে যে ব্লকের কন্ডিশনাল এক্সপ্রেশনটি সত্য শুধু সেই ব্লকটির কোড এক্সিকিউট হবে, অন্য কোনো ব্লকের কোড এক্সিকিউট হবে না। আর যদি কোনো ব্লকের শর্তই সত্য না হয়, তাহলে, সবশেষের else ব্লকের কোড
এক্সিকিউট হবে। উপরের প্রোগ্রামটির যদি ফ্লোচার্ট তৈরি করা হয়, সেটি হবে চিত্র 5.10 এর মত।
n1 = 5, n2 = 7
शौ
ni == n2 ?
n1 & n2 are equal,
n1>n2?
शां
nl is greater than n2
nl is less than n2
শেষ
চিত্র 5.8 : দুটি সংখ্যার মধ্যে ভুলনা করার ফ্লোচার্ট
এখন আরেকটি উদাহরণ দেখানো হবে।
ধরা যাক, কোনো পরীক্ষার একজন শিক্ষার্থীর প্রাপ্ত নম্বর ইনপুট নেওয়া হবে। এই নম্বরের উপর ভিত্তি করে এই বিষয়ের লেটার গ্রেড আউটপুট দেখানো হবে।
#include
{
int marks;
scanf("%d", &marks); 1f marks - 80 )
printf("Your grade is A+\n");
else if (marks >= 70) { printf("Your grade is A\n");
প্রোগ্রামিং ভাষা
}
১৭৩
else if (marks >= 60) {
} printf("Your grade is A - \n"); else if (marks >= 50) {
printf("Your grade is B\n");
} else if (marks > = 40 ) { printf("Your grade is C\n");
} else if (marks >= 33 ) { printf("Your grade is D\n");
} else{ printf("Your grade is F\n");
} return 0;
প্রোগ্রাম 5.11
এভাবে অসংখ্য if, else if যখন পরপর থাকে, তখন কোনো একটি শর্ত যদি সত্য হয়, তখন বাকি else if গুলোর শর্ত আর পরীক্ষা করা হয় না। যেমন— ইনপুট যদি হয় 75, তখন প্রথমে marks >= 80 শর্তটি পরীক্ষা করা হবে। শর্তটি মিথ্যা, তাই পরবর্তী শর্ত (marks >= 70) পরীক্ষা করা হবে। এটি সত্য। তাই এই ব্লকের ভেতরের কাজ শুরু হয়ে যাবে। এক্ষেত্রে printf() স্টেটমেন্টটি এক্সিকিউট হবে। তারপরে কিন্তু আর কোনো else if ব্লকের শর্ত পরীক্ষা করা হবে না।
নিজে করি ৪ : উপরের প্রোগ্রামে নিচের সংখ্যা ইনপুট দেওয়া হলে কী আউটপুট পাওয়া যাবে তা নির্ণয় করি :
ক) 98
খ) 80
গ) 79
ঘ) 64
) 37
চ) 23
ছ) -20
লজিকাল অপারেটর (Logical Operator)
একাধিক শর্ত মিলিয়ে নতুন শর্ত তৈরি করার জন্য গাণিতিক এক্সপ্রেশনের মতো, লজিকাল এক্সপ্রেশন লেখা যায়। বিভিন্ন শর্ত লজিকাল অপারেটর দিয়ে যুক্ত করে লজিকাল এক্সপ্রেশন তৈরি করা হয়।
সি প্রোগ্রামিং ভাষায় তিন ধরনের লজিক্যাল অপারটের আছে — && (and), || (or) এবং ! (not ) অপারেটর। অ্যান্ড (&&) অপারেটরের ক্ষেত্রে, বাম পক্ষে একটি শর্ত ও ডান পক্ষে একটি শর্ত থাকবে। যদি দুটি শর্তই সত্য হয়, তাহলে পুরো এক্সপ্রেশনটি সত্য হবে। যে কোনো একটি বা দুটি শর্তই যদি মিথ্যা হয়, তাহলে পুরো
শর্তটি মিথ্যা হবে।
A
B True
A && B
True
True
False
True
False
False
True
False
False
টেবিল 5.2
False
False
অর (||) অপারেটরের ক্ষেত্রে, বাম পক্ষে একটি শর্ত ও ডান পক্ষে একটি শর্ত থাকবে। যদি দুটি শর্তের কমপক্ষে একটি সত্য হয়, তাহলে সহ পুরো শর্তটি সত্য হবে। দুটি শর্তই যদি মিথ্যা হয়, তাহলে পুরো
শর্তটি মিথ্যা হবে।
A
B
A || B
True
True
False
True
False
True
True
False
True False
True False
টেবিল 5.3
নট (!) অপারেটরের বেলায়, অপারেটরের পরে কেবল একটি শর্ত থাকবে। শর্তটি সত্যি হলে পুরো শর্তটি মিথ্যা, আর শর্তটি মিথ্যা হলে পুরো শর্তটি সত্য হবে।
A True
!A False
False
True
উদাহরণ ৮
ধরা যাক, কোনো একটি চাকরির আবেদনকারীদের বয়সসীমা নির্ধারণ করা হলো 18 থেকে 35। এখন একটি প্রোগ্রাম লিখতে হবে, যেটি আবেদনকারীর বয়স ইনপুট নেবে এবং বয়সের হিসেবে যে আবেদন করার যোগ্য কি না, সেটি প্রিন্ট করবে।
#include
int main ()
{
int age; scanf("%d", &age);
}
if (age >= 18 && age <= 35)
{ } printf("Yes, you are eligible. \n");
else
{ printf("Sorry, you are not eligible. \n");
} return 0;
প্রোগ্রাম 5.12
উপরের প্রোগ্রামটিতে if ব্লকের ভেতরে দুটি শর্ত ব্যবহার করা হয়েছে এবং শর্ত দুটি && অপারেটর দ্বারা যুক্ত করা হয়েছে। অর্থাৎ, এক্ষেত্রে age >= 18 এবং age <= 35 দুটি শর্তই যদি সত্য হয়, তাহলে পুরো শর্তটি সত্য হবে। প্রোগ্রামটিতে যদি ! (age <18 || age 35) শর্ত ব্যবহার করা হতো, তাহলেও প্রোগ্রামটি একই কাজ করত।
উদাহরণ ৯
একটি সংখ্যা ইনপুট নেওয়া হবে। সংখ্যাটি 3 দ্বারা বিভাজ্য হলে Fizz প্রিন্ট করতে হবে, 5 দ্বারা বিভাজ্য হলে Buzz প্রিন্ট করতে হবে, আর সংখ্যাটি যদি 3 ও 5 উভয় সংখ্যা দ্বারাই বিভাজ্য হয়, তাহলে প্রিন্ট করতে হবে FizzBuzz.
কোনো সংখ্যা a যদি b দ্বারা বিভাজ্য হয়, তাহলে ভাগশেষ থাকবে । সি প্রোগ্রামিং ভাষায় ভাগশেষ বের করার অপারেটর হচ্ছে % (একে বলে মডুলাস modulus অপারেটর)। a % b-এর মান 0 হলে b দ্বারা a বিভাজ্য।
#include
int num;
scanf("%d", &num); if (num % 3 == 0 && num 85 == 0)
{ { } else if (num 85 == 0 ) {
{ printf("FizzBuzz\n");
else if (num 8 3 == 0 )
printf("Fizz\n");
printf("Buzz\n");
} return 0;
প্রোগ্রাম 5.13
নিজে করি ৫ : উপরের প্রোগ্রামটির ফ্লোচার্ট তৈরি করি।
লুপ স্টেটমেন্ট (Loop Statements)
একই কাজ বারবার করার জন্য প্রোগ্রামিং ভাষায় লুপ স্টেটমেন্ট থাকে। সি প্রোগ্রামিং ভাষায় তিন ধরনের লুপ আছে, while লুপ, do while লুপ এবং for লুপ।
while লুপ
while লুপের সিনট্যাক্স হচ্ছে—
{
while (condition)
statement ;
}
এখানে condition সত্য হলে, while-এর ব্লকের ভেতরের কাজ করা হবে। কাজ শেষে আবার condition পরীক্ষা করা হবে। এবারেও condition সত্য হলে আবারো while-এর ব্লকের ভেতরের কাজ করা হবে। এভাবে চক্রাকারে কাজটি বারবার চলতে থাকবে যতক্ষণ পর্যন্ত condition সত্য থাকে। যেমন— ধরা যাক, একটি প্রোগ্রাম লিখতে হবে, যেটি । Love Bangladesh কথাটি পাঁচবার প্রিন্ট করবে।
উদাহরণ ১০
#include
{
int i;
i = 0; while (i < 5) { printf("I Love Bangladesh.\n"); i = i + 1;
} return 0;
প্রোগ্রাম 5.14
i = 0; স্টেটমেন্টে i তে 0 রাখা হয়েছে। তারপর while-এর ভেতরের শর্ত পরীক্ষা করা হবে।। < 5 শর্তটি সত্য, কারণ i-এর মান এখন O। তারপর printf( ) স্টেটমেন্টের কাজ হবে। তারপর i = i + 1; স্টেটমেন্টটি এক্সিকিউট হবে। এই স্টেটমেন্টে i-এর মানের সঙ্গে 1 যোগ করে সেটি আবার i-তে রাখা হয়েছে (বা অ্যাসাইন করা হয়েছে)।
i-এর মান এখন 1। তারপরে আবার i < 5 শর্তটি পরীক্ষা করা হবে এবং এবারো শর্তটি সত্য (i-এর মান এখন 1)। তাই printf() ফাংশনটি এক্সিকিউট হবে। তারপরে আবার i-এর মান 1 বাড়বে। এভাবে চলতে থাকবে এবং যখন i এর মান বেড়ে 5 হবে, তখন । < 5 শর্তটি মিথ্যা হয়ে যাবে এবং প্রোগ্রামটি while লুপের বাইরে চলে আসবে। i-এর পাঁচটি মান ( 0, 1, 2, 3, 4)-এর জন্য printf() ফাংশনটি পাঁচবার এক্সিকিউট হবে এবং পাঁচবার । Love Bangladesh কথাটি প্রিন্ট হবে।
নিজে করি ৬ : কথাটি একশবার প্রিন্ট করতে চাইলে কী করতে হবে?
উদাহরণ ১১
এখন আরেকটি প্রোগ্রাম লেখা হবে, যার কাজ হবে 1 থেকে 100 পর্যন্ত সব সংখ্যা প্রিন্ট করা।
#include
{
int n;
while (n <= 100 ) { printf("%d\n", n);
n = 1; n = n + 1; }
return 0;
প্রোগ্রাম 5.15
1 থেকে 100 পর্যন্ত প্রতিটি সংখ্যা প্রিন্ট করার প্রোগ্রামের ফ্লোচার্ট 5.11 চিত্রে দেখানো হল।
শুরু
n=1
i <= 100?
না
শেষ
হ্যাঁ
n -এর মান প্রিন্ট
n = n+1
উদাহরণ ১২
এখন, 1 থেকে 100 পর্যন্ত সব জোড় সংখ্যা প্রিন্ট করার প্রোগ্রাম লেখা হবে। এটি আগের প্রোগ্রামের মতোই হবে, তবে প্রতিটি সংখ্যা প্রিন্ট করার আগে সেটি জোড় কি না, তা পরীক্ষা করা হবে। উল্লেখ্য যে, কোনো সংখ্যাকে 2 দিয়ে ভাগ করলে ভাগশেষ যদি 0 হয়, তাহলে সেটি জোড় সংখ্যা।
#include
{
int n; n = 1;
while (n <= 100) { if (n % 2 == 0) { printf("%d\n", n);
} n = n + 1;
} return 0;
প্রোগ্রামটি চাইলে এভাবেও লেখা যায়—
#include
{
int n = 2; while (n <= 100 ) { printf("%d\n", n); n = n + 2 ; }
return 0;
প্রোগ্রাম 5.16
উপরের প্রোগ্রামটিতে n-এর মান 2 থেকে শুরু হয়েছে এবং লুপের ভেতরে প্রতিবার n-এর মান 2 করে বাড়ানো হচ্ছে। তাই প্রোগ্রামটি 2 থেকে শুরু করে প্রতিটি জোড় সংখ্যা প্রিন্ট করবে এবং n-এর মান 100-এর চেয়ে বেশি হলে লুপ থেকে বের হয়ে যাবে।
উদাহরণ ১৩
এখন 1 থেকে 100 পর্যন্ত সব পূর্ণসংখ্যার যোগফল নির্ণয় করার প্রোগ্রাম লেখা হবে। যদিও ধারার সূত্র ব্যবহার করে এক লাইনেই এটি করে ফেলা যায়, কিন্তু এখানে লুপ ব্যবহার করে প্রোগ্রামটি তৈরি করা হবে। শুরুতে ধরা হবে যোগফল শূন্য। তারপর যোগফলের সঙ্গে প্রথমে 1 যোগ করা হবে, তারপর 2 যোগ করা হবে, এভাবে 100 পর্যন্ত সব সংখ্যা ওই যোগফলের সঙ্গে যোগ করা হবে।
#include
{
int n, sum; sum = 0;
n = 1; while (n <= 100) {
n; n = n + 1;
sum = sum + } printf("Result: %d\n", sum);
return 0;
প্রোগ্রাম 5.17
do-while loop: এ ক্ষেত্রে শর্ত- এর মান লুপ স্টেটমেন্ট কার্যকর হওয়ার পর নির্ধারিত হয়। অর্থ্যাৎ লুপ শর্ত পূরণ হোক বা না হোক ১ টি বারের জন্য কার্যকর হয়। এ ধরনের লুপকে exit controlled loop বলে।
do-while loop এর সিলট্যাক্স হচ্ছে :
do
{
}
statement ;
while (condition ) ;
উদাহরণ ১১ প্রোগ্রামটিকে do while লুপ ব্যবহার করে লেখা যায় ।
#include
int main()
{
int n; n=1; do
printf ("%d\n", n= n+1; n ) ;
} while (n< - 100 ),
return 0;
}
প্রোগ্রাম 5.1.8
নিজে করি ৭ : লুপ ব্যবহার করে 1 থেকে 500 পর্যন্ত সব বেজোড় সংখ্যার যোগফল নির্ণয় করার ফ্লোচার্ট তৈরি করি এবং প্রোগ্রাম লিখি।
for t
সি প্রোগ্রামিং ভাষায় for লুপের সিনট্যাক্স হচ্ছে এরকম– for ( initialization; condition; increment )
{
}
statement;
1 থেকে 100 পর্যন্ত সংখ্যাগুলো যোগ করার প্রোগ্রামটি যদি for লুপ ব্যবহার করে লেখা হয়, সেটি দাঁড়াবে
এমন-
#include
{
int n, sum; sum = 0;
for (n = 1; n = 100; n = n + 1 ) { sum = sum + n: } printf("Result: %d\n", sum); return 0;
প্রোগ্রাম 5.19
নিজে করি ৮ : এখন পর্যন্ত while লুপ ব্যবহার করে বইতে যেসব প্রোগ্রাম তৈরি করা হয়েছে, সেগুলো for
লুপ ব্যবহার করে করতে হবে।
Continue স্টেটমেন্ট
Continue স্টেটমেন্ট লুপের ভিতরে ব্যবহৃত হয়। যখন Continue স্টেটমেন্ট এর সাথে ব্যবহৃত শর্তটি সঠিক হয় তখন কন্ট্রোলটি লুপের প্রথমে চলে যায় অন্যথায় পরবর্তী স্টেটমেন্ট কার্যকর হয়। উদাহরণ:
#include
int main ()
{
int i; for ( i=1, { if {i--} continue ; printf ("%d", i); } i <=5;
i=i+1)
return 0;
}
প্রোগ্রাম 5.20
ফলাফল হবে: 2345 কারণ যখন i এর মান 1 হবে তখন সংখ্যার মানটি প্রদর্শিত না হয়ে লুপের প্রথমে
কন্ট্রোলটি চলে যাবে। ফলে 1 লেখাটি প্রদর্শিত হবে না ।
উদাহরণ ১৪
এখন for লুপ ব্যবহার করে নামতা লেখার প্রোগ্রাম তৈরি করতে হবে। প্রথমে ফ্লোচার্ট (চিত্র 5.12) তৈরি
করে দেখানো হবে, তারপর প্রোগ্রাম লেখা হবে।
শুরু
n ইনপুট
i = 1
না
i <=
10?
হ্যাঁ
i=i+1
n, in * i প্রিন্ট
শেষ
চিত্র 5.10: n-এর নামতার ফ্লোচার্ট
#include
{
int i, n;
int main ()
scanf("%d", &n ) ; for ( i = 1; i<= 10; i = i + 1 ) { printf("%d x d = %d\n", n, in * 1 ) ; }
return 0;
}
প্রয়োজন হলে একটি লুপের ভেতরে আরো লুপ ব্যবহার করা যায়। একে বলে নেস্টেড লুপ (nested loop )।
অ্যারে (Array)
একটি ভ্যারিয়েবলে একই সময়ে কেবল একটি মান রাখা যায়। কিন্তু অনেক সময় একই ধরনের অসংখ্য ভ্যারিয়েবল নিয়ে কাজ করতে হয়। যেমন— একটি ক্লাসের একশজন শিক্ষার্থীর প্রাপ্ত নম্বর আউটপুট দেওয়া।
সি প্রোগ্রামিং ভাষায় এজন্য একটি বিশেষ ডেটা স্ট্রাকচার (data structure) আছে, যার নাম অ্যারে । অ্যারেতে একই ধরনের একাধিক ডেটা রাখা যায়। অ্যারে তৈরি করার সিনট্যাক্স হচ্ছে—
data_type name [number of elements];
নিচের প্রোগ্রামটিতে একটি জ্যারে তৈরি করা হবে, যেখানে পাঁচজন শিক্ষার্থীর একটি পরীক্ষায় প্রাপ্ত নম্বর রাখা
হবে।
#include
int marks [5];
// assign marks to array
marks [0] - 87;
marks [1] - 82;
marks [2] = 76;
marks [3] = 85; marks [4] - 88;
/* now print the marks * / printf("%d\n", marks [0]); printf("%d\n", marks [1]); return 0;
printf("sd\n", marks [2] ) ; printf("%d\n", marks [3]);
printf("%d\n", marks [4]);
প্রোগ্রাম 5.21
}
উল্লেখ্য যে, প্রোগ্রামটিতে এক জায়গায় // চিহ্নের পরে, আরেক জায়গায় /* ... */ চিহ্নের ভেতরে কিছু কথা লেখা হয়েছে। এগুলোকে বলা হয় মন্তব্য বা কমেন্ট (comment)। প্রোগ্রাম কম্পাইল ও রান করার সময় এই কমেন্টগুলো কোডের অংশ হিসেবে বিবেচনা করা হয় না। প্রোগ্রামারদের নিজেদের সুবিধার্থে কমেন্ট ব্যবহার করা হয়। তাই কোনো লাইনে // থাকলে সেই লাইনে তার পরের অংশগুলো আর প্রোগ্রামের অংশ বলে ধরা হয় না। একাধিক লাইনজুয়ে কমেন্ট লিখতে চাইলে /* দিয়ে শুরু এবং */ দিয়ে শেষ করতে হয়।
প্রোগ্রাম 5.21-এ marks নামের সেই অ্যারেটি তৈরি করা হয়েছে (Int marks[5] :), সেখানে বলে দেওয়া হয়েছে যে, অ্যারেটি ইন্টিজার টাইপের অর্থাৎ অ্যারের সব উপাদান হবে ইন্টিজার আর অ্যারেতে মোট 5টি উপাদান থাকবে। অ্যারের প্রথম উপাদান থাকে এ-তম ঘরে, দ্বিতীয় উপাদান থাকে 1-তম ঘরে, তৃতীয় উপাদান থাকে 2-তম ঘরে, এরকমভাবে 12-তম উপাদান থাকে ( 12 1)-তম ঘরে। এই ঘরগুলোকে বলা হয় অ্যারের ইনডেক্স (index)। মনে রাখতে হবে যে, সি প্রোগ্রামিং ভাষায় অ্যারের ইনডেক্স থেকে শুরু হয়, 1 থেকে নয়। তাহলে marks প্যারেটিতে বিভিন্ন মান থাকবে নিচের চিত্রের মতো,
Value Index
87 0
82
1
76
2
85
3
88
4
ইনডেক্স থাকার একটি সুবিধা হচ্ছে যে, এখানে মুর্গ ব্যবহার করা যায়। যেমন— পাঁচবার printf স্টেটমেন্ট না লিখে এভাবেও দেখা যেত-
for (1 = 0; i < 5; 11+ 1) printf("%d\n", marks [i]);
}
আবার অ্যারেতে বিভিন্ন মান অ্যাসাইন করার কাজটিও সংক্ষেপে করা যায় এভাবে—
int marks []
(87, 82, 76, 85, 88);
এখানে marks-এ বলে দেওয়া নেই কয়টি উপাদান থাকৰে, তবে দ্বিতীয় বন্ধনীর ভেতরের উপাদানগুলোর
সংখ্যা থেকেই কম্পাইলার বুঝে নেয় যে অ্যারেতে কয়টি উপাদান থাকৰে ।
আবার ব্যবহারকারীর কাছ থেকে ইনপুট নিতে চাইলে সেটিও সহজে করা যায় এভাবে—
for (i = 0; i < 5; i = i + 1)
scanf("%d", &marks[i]);
}
মনে রাখতে হবে, অ্যারের ইনডেক্স সব সময় হবে একটি পূর্ণসংখ্যা, যেটি ০ থেকে শুরু হবে। আর অ্যারেতে 12 সংখ্যক উপাদান থাকলে অ্যারের ইনডেক্স-এর সর্বোচ্চ মান হবে 1 - 11
উদাহরণ ১৬
একটি অ্যারেতে দশটি সংখ্যা রাখা আছে। সংখ্যাগুলোর যোগফল বের করতে হবে-
#include
int numbera [10] = {9, 76, 2, 45, 3, 81, 25, 33, 71, 10);
int i, sum; sum - 07
for (i = 0; i < 10; i = i + 1} {
gum = sum + numbers [i] ;
printf("Sum: %d\n", sum); return 0;
প্রোগ্রাম 5.32
একটি ফাংশনে যখন কোনো ভ্যারিয়েবল ডিক্লেয়ার করা হয় (যেমন int sum), তখন সেই ড্যারিয়েবলের ভেতরে কোনো মান দেওয়া থাকে না। সেই ভ্যারিয়েবলটির ভেতরে যে কোনো মান থাকতে পারে, যাকে পারবেজ (garbage) মান বলা হয়। তাই ড্যারিয়েবলটির ভেতর যদি রাখার প্রয়োজন হয়, তখন এর মধ্যে ০ অ্যাসাইন করতে হবে (যেমন sum = 0)। আর যোগফল নির্ণয়ের প্রোগ্রামটিতে এমনটি করতে হয়েছে
কারণ sum = sum + numbers [i] স্টেটমেন্ট চলার আগে sum-এর মান 0 করে দেওয়ার ফলে 0 +9 অর্থাৎ 9 সংখ্যাটি sum-এর মধ্যে আবার রাখা যাচ্ছে।
a = a + b; এই স্টেটমেন্টটি সি ভাষায় আরেকভাবে লেখা যায় : a + b; তাহলে প্রোগ্রাম 5.22-এ for লুপটি এভাবে লেখা যায়,
for (i { 0; i < 10; i += 1)
sum + = numbers [i] ;
}
আবার i += 1 (বা, i = 1 + 1)-কে i++ লেখা যায়। এটি একটি সংক্ষিপ্ত রূপ। যে কোনো একভাবে লিখলেই
চলে।
উদাহরণ ১৭
একটি অ্যারেতে পাঁচটি সংখ্যা আছে। একটি প্রোগ্রাম লিখে সংখ্যাগুলোর ক্রম উল্টে দিতে হবে। অর্থাৎ অ্যারেতে যদি 1, 2, 3, 4, 5 থাকে, তাহলে প্রোগ্রামটি অ্যারেতে 5, 4, 3, 2, 1 নিয়ে আসবে।
প্রোগ্রামটি লেখার আগে একটি অপেক্ষাকৃত সহজ প্রোগ্রাম করে দেখতে হবে। ধরা যাক, দুটি ভ্যারিয়েবল আছে, a ও b। এখন একটি প্রোগ্রাম লিখতে হবে যেন, a-এর মান b-তে চলে আসে আর b-এর মান a-তে চলে আসে। কাজটি করার উপায় কী? একটি সহজ উপায় হচ্ছে, অতিরিক্ত একটি ভ্যারিয়েবল C ব্যবহার করা। তারপরে c-এর ভেতরে a-এর মান অ্যাসাইন করা। তাহলে এখন c ও a-তে একই মান থাকবে। এখন b-এর মান a-তে অ্যাসাইন করা হবে। তাহলে c-তে থাকবে a-এর আসল মান, a ও b তে থাকবে b-এর মান। তারমানে b-এর মান কিন্তু a-তে চলে এলো। এখন, a-এর আসল মান b-তে আনতে পারলেই কাজ শেষ। c-এর মধ্যে a-এর আসল মান আছে। তাই b = c; লিখলেই কাজ হয়ে যাবে। বিষয়টি অনেকটা নিচের ছবির মতো।
A
13
B
B
চিত্র 5.11 : ছবিতে a পাত্রে হলুদ রঙের আইসক্রিম এবং b পাত্রে গোলাপি রঙের আইসক্রিম রয়েছে। আমরা চাই, a পাত্রের আইসক্রিম b পাত্রে নিয়ে আসতে এবং b পাত্রের আইসক্রিম a পাত্রে নিয়ে আসতে
#include
int a int c; = 15, b = 9 ;
C a;
= b;
b = c; printf("Value of a is %d, value of b is %d\n", a, b);
return 0;
প্রোগ্রাম 5.23
নিজে করি ৯ : উপরের প্রোগ্রামটির অ্যালগরিদম লিখতে হবে এবং ফ্লোচার্ট তৈরি করতে হবে।
এখন আসল সমস্যাটির সমাধান করা হবে। অ্যারের প্রথম উপাদনের সঙ্গে শেষ উপাদানের মানের অদলবদল করা হবে, তারপর অ্যারের দ্বিতীয় উপাদানের সঙ্গে অ্যারের শেষ উপাদানের আগের উপাদানের মানের অদলবদল করা হবে।
প্রোগ্রামটি লেখা যায় এভাবে—
#include
int main ()
{
int ara[] = {10, 20, 30, 40, 50}; int n = 5, i;
int _temp;
for ( i = 0; i
// exchange value of ara[i] and ara [n-1-i] temp = ara [i] ;
ara[i] = ara [n-1-i] ; Sara [n-1-i] = temp;
}
for ( i = 0;i
printf("%d\n", ara[i]);
}
}
return 0;
প্রোগ্রাম 5.24
উপরের প্রোগ্রামটি কম্পাইল ও রান করে দেখতে হবে।
নিজে করি ১০ : প্রথম for লুপে শর্ত ব্যবহার করা হয়েছে i
সি প্রোগ্রামিং ভাষায় ক্যারেক্টার টাইপের ভ্যারিয়েবলে একটি অক্ষর রাখা যায়। যদি একাধিক অক্ষর রাখতে হয়, তখন ক্যারেক্টার টাইপের অ্যারে ব্যবহার করা হয়। একে বলা হয় স্ট্রিং (string)। বিভিন্ন প্রোগ্রামিং ভাষায় স্ট্রিংয়ের জন্য পৃথক ডেটা টাইপ থাকলেও সি-তে আলাদা কোনো ডেটা টাইপ নেই।
উদাহরণ ১৮
নিচের প্রোগ্রামের মাধ্যমে দেখানো হবে সি-তে কীভাবে স্ট্রিং ইনপুট নেওয়া যায় ও আউটপুট দেওয়া যায়,
#include
int main() { char name [80] ; scanf("%s", name); printf("%s\n", name);
return 0;
প্রোগ্রাম 5.25
যেই স্ট্রিং ইনপুট দেওয়া হবে, প্রোগ্রামটি সেই স্ট্রিং আউটপুট হিসেবে প্রিন্ট করবে। একটি স্ট্রিংয়ের শেষ অক্ষরটি হবে নাল ক্যারেক্টার ('\O')। তাই কোনো স্ট্রিংয়ে যদি বলে দেওয়া হয় সর্বোচ্চ ৪০টি ঘর থাকবে (name[80]), তাহলে এখানে আসলে সর্বোচ্চ 79টি অক্ষর রাখা যাবে। শেষ ঘরটি নাল ক্যারেক্টারের জন্য বরাদ্দ রাখতে হবে।
সাধারণ ইন্টিজার অ্যারেতে ইনপুট নিতে হলে যেমন একটি লুপ ব্যবহার করে একটি একটি করে সংখ্যা ইনপুট নিতে হয়, ক্যারেক্টার অ্যারে বা স্ট্রিংয়ের ক্ষেত্রে তার প্রয়োজন হয় না। scanf() ফাংশনের ভেতরে %s ব্যবহার করে সম্পূর্ণ স্ট্রিংটি একবারে ইনপুট নেওয়া যায়। তবে স্ট্রিংয়ের ভেতরে কোনো স্পেস (space) ক্যারেক্টার থাকতে পারবে না।
নিচের ছবিতে একটি স্ট্রিং "Bangla" কীভাবে অ্যারেতে থাকে, সেটি দেখানো হয়েছে—
Value
Index
'B'
0
'a'
1
'n'
2
'g'
3
ין'
4
'a'
5
6
উদাহরণ ১৯
এখন একটি প্রোগ্রাম লেখা হবে, যেটি একটি স্ট্রিংয়ে কতগুলো অক্ষর বা ক্যারেক্টার আছে, সেটি বের
করবে-
#include
{ char name [80] ; int i, length; scanf("%s", name); i = 0; while (name [i] = 1 \0 ' ) { } 1 = 1 + 1;
length = 1; printf("%s has %d characters.\n", name, length); return 0;
প্রোগ্রাম 5.26
এখানে i-তে 0 অ্যাসাইন করা হয়েছে। তারপর while লুপের ভেতরে শর্ত পরীক্ষা করা হচ্ছে যে, name[i]- এর মান নাল ক্যারেক্টার কি না। যদি না হয়, তাহলে লুপের ভেতরে i-এর মান এক বাড়ানো হয়েছে। যখন name[i]-এর মান নাল ক্যারেক্টারের সমান হবে, তখন প্রোগ্রামটি লুপ থেকে বের হয়ে যাবে। আর i-এর মানই হবে স্ট্রিংয়ের দৈর্ঘ্য, যেটি length নামক ভ্যারিয়েবলে অ্যাসাইন করা হয়েছে। উল্লেখ্য যে, একটি স্ট্রিংয়ে মোট অক্ষরের সংখ্যাকে সেই স্ট্রিংয়ের দৈর্ঘ্য বলা হয়।
উদাহরণ ২০
একটি অ্যারেতে অনেকগুলো সংখ্যা আছে। একটি নির্দিষ্ট সংখ্যা ইনপুট দেওয়া হবে এবং সংখ্যাটি ওই অ্যারেতে আছে কি না, সেটি বের করতে হবে। প্রথমে ফ্লোচার্ট আঁকতে হবে, তারপরে কোড লিখতে হবে।
শুরু
Key ইনপুট
i=0
না
i < n?
i+= 1
ara[i]==
key?
না
প্রিন্ট Found!
i == n?
না
হ্যাঁ
fe Not found!
শেষ
কোড—
চিত্র 5.12 : অ্যারেতে সংখ্যা খোঁজার ফ্লোচার্ট
#include
int main() {
int ara[] [1, 2, 3, 5, 8, 13, 21, 34, 55}; = int key, i, n;
n = 9;
scanf("%d", &key);
for (i = 0; i < n; i += 1) {
if (ara[i] key) == {
printf("%d is found in the array. \n", key); break;
}
}
if (i n) ==
{ } printf("%d is not found in the array. \n", key);
return 0;
প্রোগ্রাম 5.27
উপরের প্রোগ্রামে break স্টেটমেন্ট ব্যবহার করা হয়েছে। এই স্টেটমেন্ট এক্সিকিউট হলে লুপের ভেতর থেকে প্রোগ্রামটি বের হয়ে যাবে। key যদি অ্যারেতে পাওয়া যায়, তাহলে আর খোঁজার কোনো প্রয়োজন নেই, তাই লুপ থেকে বের হয়ে যেতে হবে। লুপ থেকে বের হওয়ার তাহলে দুটি উপায়, এক হচ্ছে break; এক্সিকিউট হওয়া, আর নইলে সব সংখ্যা পরীক্ষা করা হয়ে গেলে i এর মান n-এর সমান হয়ে যাবে, তখন i < n শর্তটি মিথ্যা হয়ে যাবে আর প্রোগ্রামটি লুপ থেকে বের হয়ে যাবে। তাই for লুপের ব্লকের বাইরে পরীক্ষা করা হচ্ছে যে, i আর n-এর মান সমান কি না। যদি সমান হয়, তাহলে বুঝতে হবে break স্টেটমেন্ট এক্সিকিউট হয়নি, অর্থাৎ সংখ্যাটি খুঁজে পাওয়া যায়নি। এই পদ্ধতিতে বলা হয় লিনিয়ার সার্চ (linear search) I
নিজে করি ১১ : একটি অ্যারেতে ছয়টি সংখ্যা আছে, সেগুলো হচ্ছে যথাক্রমে 5, 8, 1, 9, 4, 10। এখান থেকে 4 সংখ্যাটি লিনিয়ার সার্চ পদ্ধতিতে খুঁজে বের করার ধাপগুলো দেখাই (কোড না লিখে)।
ফাংশন (Function)
প্রোগ্রামাররা বিভিন্ন সময় যখন প্রোগ্রাম লেখে, তখন দেখা যায়, একই কাজ একাধিকবার করতে হচ্ছে। এ কাজগুলো একসঙ্গে একটি ফাংশনের মধ্যে লেখা যায়। তখন কেবল সেই ফাংশনটি কল করলেই চলে, ভেতরের কাজগুলো আবার নতুন করে লিখতে হয় না। এমনকি, ফাংশনটি ভেতরে কীভাবে কাজ করছে, সেটি না জানলেও ফাংশনটি ব্যবহার করতে সমস্যা হয় না ।
ইতিমধ্যে বইতে printf( ) ও scanf() ফাংশনের ব্যবহার দেখানো হয়েছে। এখন স্ক্রিনে প্রিন্ট করার জন্য অনেক কাজ করতে হয় বা কোড লিখতে হয়। সেগুলো printf() ফাংশনের ভেতরে বলা আছে। কিন্তু সি প্রোগ্রামাররা সরাসরি printf() ফাংশন ব্যবহার করে, printf()-এর ভেতরে যে কোড লেখা আছে, সেটি যদি বারবার লিখতে হতো, তাহলে প্রোগ্রামারদের কষ্টও বেড়ে যেত, কোডের আকারও বেড়ে যেত। তেমনি scanf() ফাংশনের বেলাতেও ব্যাপারটি সত্য। ফাংশনটি কীভাবে ব্যবহার করতে হবে, সি প্রোগ্রামারদের এটুকু জানাই যথেষ্ট। এই ফাংশন দুটো ব্যবহার করার জন্য stdio.h নামক হেডার ফাইলটি ইনক্লুড করতে হয়। একটি হেডার ফাইল ইনক্লুড করলে ওই হেডার ফাইলের ভেতরে যেসব ফাংশন তৈরি করে দেওয়া থাকে, সেগুলো ব্যবহার করা যায়। সি প্রোগ্রামিং ভাষায় এরকম অনেক হেডার ফাইল তৈরি করে দেওয়া
আছে। এগুলোকে লাইব্রেরিও বলে। এছাড়া প্রয়োজন হলে প্রোগ্রামার নতুন হেডার ফাইল তৈরি করে নেয়। একটি ফাংশন ব্যবহার করতে হলে তিনটি জিনিস জানতে হয়। ফাংশনটি কী কাজ করে, ফাংশনের ভেতরে কী কী ডেটা পাঠাতে হবে, আর ফাংশনটি কী ডেটা রিটার্ন করে। যেমন- math.h হেডার ফাইলে একটি ফাংশন আছে যার কাজ হচ্ছে বর্গমূল বের করা। ফাংশনটির প্রোটোটাইপ হচ্ছে - double sqrt(double arg); এখানে প্রথম double হচ্ছে ফাংশনটির রিটার্ন টাইপ, অর্থাৎ ফাংশনটি কী টাইপের ডেটা রিটার্ন করে। ফাংশন যদি কোনো ডেটা রিটার্ন না করে, তখন রিটার্ন টাইপ হয় void। তারপরে sqrt হচ্ছে— ফাংশনের নাম। এরপর প্রথম বন্ধনীর ভেতরে double arg লেখা, যার অর্থ হচ্ছে ফাংশনটি ইনপুট হিসেবে একটি double টাইপের ডেটা গ্রহণ করে— একে বলা হয় ফাংশনের প্যারামিটার (parameter)। আর ফাংশনটি যখন ব্যবহার করা হয়, তখন প্যারামিটারের জায়গায় যে ডেটা পাঠানো হয়, তাকে বলা হয় আর্গুমেন্ট (argument)। নিচের উদাহরণে ফাংশনটির ব্যবহার দেখানো হলো।
উদাহরণ ২১
#include
int main () {
double num, root;
scanf("%lf", &num);
root = sqrt (num) ;
printf("Square root of %lf is %lf\n", num, root);
return 0;
}
প্রোগ্রাম 5.28
main() ফাংশনের শেষে কেন return 0; স্টেটমেন্টটি লেখা হয়? সি ল্যাঙ্গুয়েজে লেখা সব প্রোগ্রাম রান করলে কোডের ভেতরে main() ফাংশন থেকে প্রোগ্রামটি চলা শুরু হয়। main() ফাংশন যদি এভাবে ডিক্লেয়ার করা হয়— int main() তাহলে কম্পাইলার ধরে নেয় যে ফাংশনটি যখন এক্সিকিউশন শেষ হবে তখন সে একটি ইন্টিজার রিটার্ন করবে। তাই ফাংশনের শেষে কোনো একটি ইন্টিজার রিটার্ন করতে হবে। প্রচলিত নিয়মে 0 রিটার্ন করা হয়, প্রোগ্রামটি ঠিকভাবে কোনো সমস্যা ছাড়াই চলেছে সেটা বোঝানোর জন্য। তবে 0-ই যে রিটার্ন করতে হবে এমন কোনো কথা নেই। চাইলে যেকোনো ইন্টিজার-ই রিটার্ন করা যায়।
math.h হেডার ফাইলে আরেকটি ফাংশন হচ্ছে pow ( double x, double y); | এই ফাংশনটি প্যারামিটার হিসেবে দুটি double টাইপের সংখ্যা গ্রহণ করে এবং x এর মান হিসেব করে রিটার্ন করে। যেমন — x এর মান 3 আর 3-এর মান 2 পাঠালে ফাংশনটি 9 রিটার্ন করবে।
উদাহরণ ২২
#include
int main()
double p, x, yi
{ scanf("%lf %lf", &x, &y); printf("%lf to the power %lf is: %lf\n", x, y, p); }
p = pow (x, y) ;
return 0;
প্রোগ্রাম 5.29
math.h হেডার ফাইলে এরকম অনেক গাণিতিক ফাংশন তৈরি করে দেওয়া আছে। একটি স্ট্রিংয়ের দৈর্ঘ্য, অর্থাৎ স্ট্রিংয়ে মোট কয়টি ক্যারেক্টার আছে, সেটি বের করার জন্য ইতিমধ্যে বইতে একটি প্রোগ্রাম লিখে দেখানো হয়েছে। কাজটি চাইলে একটি লাইব্রেরি ফাংশন ব্যবহার করে করা যায়, যার নাম হচ্ছে strlen। ফাংশনটি ইনপুট হিসেবে একটি স্ট্রিং নিবে এবং তার দৈর্ঘ্য রিটার্ন করবে। এই ফাংশনটি রয়েছে string.h হেডার ফাইলে।
উদাহরণ ২৩
#include
int main ()
char name [80]; int length;
{ scanf("%s", name);
length = strlen(name);
printf("%s has %d characters.\n", name, length);
return 0;
}
15.30
দুটি স্ট্রিং সমান নাকি বড়-ছোট, সেটি বের করার জন্য streamp নামক একটি লাইব্রেরি ফাংশন আছে। যার কাজ হচ্ছে দুটি স্ট্রিং তুলনা করে সমান হলে রিটার্ন করা, প্রথমটি বড় হলে 1 রিটার্ন করা আর প্রথমটি ছোট হলে – 1 রিটার্ন করা।
উল্লেখ্য, এখানে বড়-ছোট মানে দৈর্ঘ্যে বড়-ছোট নয়, বরং লেক্সিকোগ্রাফিক্যালি (lexicographically) বড়- ছোট কি না তা বোঝানো হয়েছে। এর মানে হচ্ছে ডিকশনারি বা আভিধানিক ক্রমে সাজানে যে স্ট্রিংটি আগে আসবে তাকে ছোট আর যেটি পরে আসবে তাকে বড় বলে বিবেচনা করা হবে।
উদাহরণ ২৪
#include
int main ()
value = strcmp(a1, a2);
char s1[80], s2 [80]; int value; if (value == 0) else if (value > 0) } else
printf("%s and as are equal.\n", sl, s2);
printf("%s is greater than s.\n", s1, 82);
{ } printf("%s is smaller than s.\n", s1, 82);
return 0;
}
নিজে করি ১৩ : একটি প্রোগ্রাম তৈরি করতে হবে যেটি একটি স্ট্রিং ইনপুট দিলে সেই স্ট্রিংটি প্রিন্ট করবে, তবে quit ইনপুট দিলে প্রোগ্রামটি বন্ধ হয়ে যাবে। যেমন নিচের ছবিতে দেখা যাচ্ছে যে quit ইনপুট দেওয়ার আগ পর্যন্ত যা ইনপুট দেওয়া হচ্ছে, তা-ই প্রিন্ট হচ্ছে।
hi hi
hello
hello
good good
bad bad
quit
এতক্ষণ বিভিন্ন লাইব্রেরি ফাংশনের ব্যবহার দেখানো হলো। সি প্রোগ্রামিং ভাষায় এরকম শত শত লাইব্রেরি ফাংশন আছে। কম্পাইলারের সঙ্গে দেওয়া ডকুমেন্টেশন কিংবা ইন্টারনেট ঘেঁটে সেই লাইব্রেরি ফাংশনগুলো সম্পর্কে জানা যাবে।
এখন দেখানো হবে কীভাবে নতুন ফাংশন তৈরি করতে হয়।
উদাহরণ ২৫
#include
float celsius_to_fahrenheit (float celsius);
int main ()
{
float celsius, fahrenheit;
scanf("%f", &celsius ) ;
fahrenheit = celsius_to_fahrenheit (celsius ) ;
printf("Fahrenheit = 8f \n", fahrenheit );
return 0;
}
float celsius_to_fahrenheit (float celsius) {
return (celsius * 9 / 5 ) + 32;
}
উপরের প্রোগ্রামে celsius_to_fahrenheit() নামে একটি ফাংশন তৈরি করা হয়েছে। ফাংশনটি একটি সংখ্যা প্যারামিটার হিসেবে নেয় যেটি ডিগ্রি সেলসিয়াস এককে একটি তাপমাত্রা নির্দেশ করে এবং সংখ্যাটি ডিগ্রি ফারেনহাইট এককে রূপান্তর করে রিটার্ন করে। main() ফাংশন লেখার আগে ফাংশনটির প্রোটোটাইপ লেখা হয়েছে—
float celsius_to_fahrenheit (float celsius ) ;
তারপর main() ফাংশনের পরে ফাংশনটি ইমপ্লিমেন্ট করা হয়েছে। main() ফাংশন থেকে যখন celsius_to_fahrenheit() ফাংশনটি কল (call) করা হচ্ছে, তখন প্রোগ্রাম এই ফাংশনের ভেতরে ঢুকে যাচ্ছে এবং ফাংশন থেকে যখন রিটার্ন করা হচ্ছে, তখন আবার main() ফাংশনের ভেতরে ফেরত আসছে।
নিজে করি ১৩ : ফাংশন ব্যবহার করে যে কোনো সংখ্যা ইনপুট প্রদান করলে ঐ সংখ্যার নামতা প্রদর্শনের
জন্যে প্রোগ্রাম লিখ ।
উদাহরণ ২৬
1 থেকে 100 পর্যন্ত প্রতিটি সংখ্যার জন্য সংখ্যাটি 3 দ্বারা বিভাজ্য হলে Fizz প্রিন্ট করতে হবে, 5 দ্বারা বিভাজ্য হলে Buzz প্রিন্ট করতে হবে, আর সংখ্যাটি যদি 3 ও 5 উভয় সংখ্যা দ্বারাই বিভাজ্য হয়, তাহলে প্রিন্ট করতে হবে FizzBuzz. প্রতিটি সংখ্যা পরীক্ষা করার কাজটি একটি ফাংশন ব্যবহার করে করতে হবে।
#include
void fizzbuzz (int n);
int main()
int i;
for ( i = 1; 1 <= 100; i + = 1) { printf("%d: ", i); fizzbuzz (i); }
}
return 0;
void fizzbuzz (int n)
{
if (n % 3 == 0 && n % 5 == 0) { printf("FizzBuzz\n");
}
else if (n % 3 == 0) { printf("Fizz\n");
}
else if (n % 5 ==0) { printf("Buzz\n");
} else {
printf("\n");
}
}
প্রোগ্রাম 5.32
আরও দেখুন...